package com.catcoin.finance.scheduledExecutorService;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.catcoin.finance.mapper.AccountMapper;
import com.catcoin.finance.model.*;
import com.catcoin.finance.service.*;
import com.catcoin.finance.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class ScheduledService {
    @Autowired
    private ISysConfigsService iSysConfigsService;
    @Autowired
    private IAccountService iAccountService;
    @Autowired
    private ILogPurseAccrualService iLogPurseAccrualService;
    @Autowired
    private ILogPurseCorpusService iLogPurseCorpusService;
    @Autowired
    private ToolfeignInterface toolfeignInterface;
    @Autowired
    private AccountMapper accountMapper;
    @Autowired
    private IMoneyccService iMoneyccService;
    /**
     * 利率
     */
    private BigDecimal  interestRate;
    /**
     * 本金清零前提（倍数）
     */
    private BigDecimal toZero;

    /**
     * 定时任务
     */
    @Scheduled(cron = "0 0 0 * * ?")
    //@Scheduled(cron = "5/5 * 11 * * ?")
    public void purseAccrual(){
        try {
            System.out.println("**********************开始定时任务**********************");
            //查询配置属性表
            SysConfigs interestRates = iSysConfigsService.selectOne(new EntityWrapper<SysConfigs>().eq("fieldCode", "rateOfInterest"));
            SysConfigs walletEmptys = iSysConfigsService.selectOne(new EntityWrapper<SysConfigs>().eq("fieldCode", "walletEmpty"));
            //当日利率
            interestRate = new BigDecimal(interestRates.getFieldValue()).divide(new BigDecimal(100));
            //本金清零前提（倍数）
            toZero = new BigDecimal(walletEmptys.getFieldValue());
            //查询用户表
            List<AccountDTO> accountList = iAccountService.selectAllList();
            Boolean result = this.addPurseAccrual(accountList);
            System.out.println("**********************结束定时任务**********************"+result);
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("**********************定时任务异常**********************");
        }
    }


    public Boolean addPurseAccrual(List<AccountDTO> accountList){
        //利息不足本金三到五倍
        List<Account> inAccountList = new ArrayList<>();//批量修改用户账户表数据（加利息）
        List<LogPurseAccrual> inLogPurseAccrual = new ArrayList<>();//批量新增理财钱包利息流水（加利息）
        List<Moneycc> moneyccList = new ArrayList<>();//批量修改理财钱包记录(修改产生利息总和,修改剩余利息)
        //利息达到本金三到五倍
        List<Account> accountToZeroList = new ArrayList<>();//批量修改用户账户表数据（清空本金，不加利息）
        List<LogPurseCorpus> inLogPurseCorpus = new ArrayList<>();//批量新增理财钱包本金流水(清空本金)
        List<Moneycc> moneyccList2 = new ArrayList<>();//批量修改理财钱包记录(修改状态为0，不产生利息，可以提现)
        Boolean isOk = false; //是否批量更新成功
        if (!accountList.isEmpty()) {
            for (AccountDTO ad : accountList) {
                //没本金不走
                if (ad.getMoneycc().compareTo(new BigDecimal("0")) == 0) {
                    continue;
                }
                //分别查询理财钱包可产生利息的记录
                List<Moneycc> moneyccsList = iMoneyccService.selectList(new EntityWrapper<Moneycc>()
                        .eq("status", 1)
                        .eq("userId", ad.getUserId()));
                //遍历这些记录，做判断(利息是否达到本金三到五倍)，产生利息/清空本金(修改status)
                for (Moneycc moneycc : moneyccsList) {
                    //当日利息(本金的1%-1.5%后台可控)
                    BigDecimal todayAccrual = moneycc.getMoneyccValue().multiply(interestRate).setScale(6, BigDecimal.ROUND_DOWN);

                    //如果本金*3 小于或者等于 当前利息加当日应产生利息 不走定时任务生成利息   直接清空本金
                    if (moneycc.getMoneyccValue().multiply(toZero).compareTo(moneycc.getTotalAccrual().add(todayAccrual)) != 1) {
                        //先本金流水
                        LogPurseCorpus logPurseCorpus = this.newLogPurseCorpus(ad, moneycc);
                        inLogPurseCorpus.add(logPurseCorpus);
                        //后本金清零
                        moneycc = this.updateMoneyccStatus(ad, moneycc);
                        moneyccList2.add(moneycc);
                        //用户表减去相应的本金金额，本金清零总利息增加，本金未清零总利息减少
                        Account account = this.updateAccountToZero(ad, moneycc);
                        accountToZeroList.add(account);
                        continue;
                    }
                    //先创建理财利息增加流水
                    LogPurseAccrual logPurseAccrual = this.newLogPurseAccrual(ad, moneycc, todayAccrual);
                    inLogPurseAccrual.add(logPurseAccrual);
                    //增加利息
                    moneycc = this.updateMoneyccAccrual(ad, moneycc,todayAccrual);
                    moneyccList.add(moneycc);
                    //后修改账户表(增加可用利息，增加本金未清零利息，增加钱包产生利息总和)
                    Account account = this.updateAccount(ad, todayAccrual);
                    inAccountList.add(account);
                }
            }
            //批量更新
            if(accountToZeroList.isEmpty() && inLogPurseCorpus.isEmpty() && moneyccList2.isEmpty()){
                Boolean ac = iAccountService.updateBatchById(inAccountList);
                Boolean lpa = iLogPurseAccrualService.insertBatch(inLogPurseAccrual);
                Boolean mc = iMoneyccService.updateBatchById(moneyccList);
                if(ac && lpa && mc){
                    isOk = true;
                }
                return isOk;
            }
            Boolean ac = iAccountService.updateBatchById(inAccountList);
            Boolean lpa = iLogPurseAccrualService.insertBatch(inLogPurseAccrual);
            Boolean mc = iMoneyccService.updateBatchById(moneyccList);

            Boolean acToZero = iAccountService.updateBatchById(accountToZeroList);
            Boolean lpc = iLogPurseCorpusService.insertBatch(inLogPurseCorpus);
            Boolean mc2 = iMoneyccService.updateBatchById(moneyccList2);
            if(ac && lpa && mc && acToZero && lpc && mc2){
                isOk = true;
            }
            return isOk;
        }
        return isOk;
    }



    /**
     * 修改账户表
     * @param ad
     * @param multiply
     * @return
     */
    public Account updateAccount(AccountDTO ad,BigDecimal todayAccrual){
        ad.setIeterestcc(ad.getIeterestcc().add(todayAccrual));
        ad.setMoneyNoZeroIt(ad.getMoneyNoZeroIt().add(todayAccrual));
        ad.setIeterestccTotal(ad.getIeterestccTotal().add(todayAccrual));
        return ad;
    }
    /**
     * 修改账户表,当用户理财利息达到理财本金的三到五倍系统清零本金
     * @param ad
     * @return
     */
    public Account updateAccountToZero(AccountDTO ad,Moneycc moneycc){
        ad.setMoneycc(ad.getMoneycc().subtract(moneycc.getMoneyccValue()));
        ad.setMoneyNoZeroIt(ad.getMoneyNoZeroIt().subtract(moneycc.getNowAccrual()));
        ad.setMoneyToZeroIt(ad.getMoneyToZeroIt().add(moneycc.getNowAccrual()));
        return ad;
    }

    public Moneycc updateMoneyccStatus(AccountDTO ad,Moneycc moneycc) {
        moneycc.setStatus(0);
        return moneycc;
    }
    public Moneycc updateMoneyccAccrual(AccountDTO ad,Moneycc moneycc,BigDecimal totalAccrual) {
        moneycc.setTotalAccrual(moneycc.getTotalAccrual().add(totalAccrual));
        moneycc.setNowAccrual(moneycc.getNowAccrual().add(totalAccrual));
        return moneycc;
    }


    /**
     * 创建理财本金清空流水
     * @param ad
     * @return
     */
    public LogPurseCorpus newLogPurseCorpus(AccountDTO ad,Moneycc moneycc){
        LogPurseCorpus logPurseCorpus = new LogPurseCorpus();
        logPurseCorpus.setUserId(ad.getUserId());
        logPurseCorpus.setFromId(ad.getUserId());
        logPurseCorpus.setMoneyccId(moneycc.getId());
        logPurseCorpus.setOrderNo(StringUtils.getOrderIdByTime("5"));
        logPurseCorpus.setPrePurseCorpus(moneycc.getMoneyccValue());
        logPurseCorpus.setPurseCorpus(moneycc.getMoneyccValue());
        logPurseCorpus.setPurseCorpusType(-1);
        logPurseCorpus.setRemark("理财利息达到本金清空倍数");
        logPurseCorpus.setDataFlag(1);
        logPurseCorpus.setCreateTime(new Date());
        logPurseCorpus.setType(5);
        return logPurseCorpus;
    }

    /**
     *  创建理财利息流水
     * @param ad
     * @param multiply
     * @return
     */
    public LogPurseAccrual newLogPurseAccrual(AccountDTO ad,Moneycc moneycc,BigDecimal todayAccrual){
        LogPurseAccrual logPurseAccrual = new LogPurseAccrual();
        logPurseAccrual.setUserId(ad.getUserId());
        logPurseAccrual.setFromId(ad.getUserId());
        logPurseAccrual.setMoneyccId(moneycc.getId());
        logPurseAccrual.setOrderNo(StringUtils.getOrderIdByTime("4"));
        logPurseAccrual.setPrePurseAccrual(moneycc.getNowAccrual());
        logPurseAccrual.setPurseAccrual(todayAccrual);
        logPurseAccrual.setPurseAccrualType(1);
        logPurseAccrual.setRemark("理财钱包本金当日利息");
        logPurseAccrual.setDataFlag(1);
        logPurseAccrual.setCreateTime(new Date());
        logPurseAccrual.setType(4);
        return logPurseAccrual;
    }


    /**
     * 获取交易所用户id
     * @param userPhone
     * @return
     */
    public String selectJiaoYiSuo(String userPhone){
        String result = toolfeignInterface.register(userPhone);
        if(!"error".equals(result)){
            JSONObject jsonObject = JSONObject.parseObject(result);
            if("true".equals(jsonObject.get("isSuc").toString())){
                JSONObject jsonObject1 = JSONObject.parseObject(jsonObject.get("datas").toString());
                return jsonObject1.get("userID").toString();
            }
        }
        return "error";
    }


    //判断用户理财钱包利息是否达到理财本金的3-5倍（可调）
    public Integer judgement(Account ad,BigDecimal multiply){
       return ad.getMoneycc().multiply(toZero).compareTo(ad.getIeterestcc().add(multiply));
    }

}
